package com.zhangh.summer.admin.support.utils.json;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.math.BigDecimal;

/**
 * @description: TODO
 * @author: zhanghui  zhanghlucky@163.com
 * @create: 2021-06-09 23:19
 **/

@Slf4j
public class JsonEncoder implements StringEncoder {
    public static final JsonEncoder DEFAULT = new JsonEncoder();
    private static  final ObjectMapper mapper ;
    static {
        mapper = new ObjectMapper();
    }
    public JsonEncoder() {

    }

    /**
     * 转json
     * @param t 对象
     * @param <T> 对象类型
     * @return json
     */
    public<T> String encode(T t) {
        String json=null;
        try {
            json= JSON.toJSONString(t);
            return  json;
        } catch (Exception e) {
            log.error("object to json error:{}",e.getMessage());
            e.printStackTrace();
        }
        return  json;
    }

    /**
     * 转json 格式化
     * @param t 对象
     * @param <T> 对象类型
     * @return json 格式化
     */
    public<T> String prettyEncode(T t) {
        String json= null;
        try {
            json = JSON.toJSONString(t,true);
        } catch (Exception e) {
            log.error("object to json error:{}",e.getMessage());
            e.printStackTrace();
        }
        return json;
    }

    /**
     * 解码json 格式：Object
     * @param json json
     * @param cls 对象 cls
     * @param <T> 对象类型
     * @return 对象
     */
    public <T> T decode(String json, Class<T> cls) {
        if (cls.getSimpleName().equals(String.class.getSimpleName())
                ||cls.getSimpleName().equals(Integer.class.getSimpleName())
                ||cls.getSimpleName().equals(Long.class.getSimpleName())
                ||cls.getSimpleName().equals(Double.class.getSimpleName())
                ||cls.getSimpleName().equals(BigDecimal.class.getSimpleName())
                ||cls.getSimpleName().equals(Boolean.class.getSimpleName())
                ||cls.getSimpleName().equals(Short.class.getSimpleName())
        ){
            return (T)json;
        }

        try {
            return JSON.parseObject(json,cls);
        } catch (Exception e) {
            log.error("json to object error:{},json:{}",e.getMessage(),json);
            e.printStackTrace();
        }
        return null;
    }


   /* @Deprecated
    public <T> T decode(String json, Class<T> clazz, Class... constructClazzs) {
        JavaType javaType;
        if (!clazz.getSimpleName().equals(Map.class.getSimpleName())&&constructClazzs.length==2){
            JavaType dataType = mapper.getTypeFactory().constructParametricType(constructClazzs[0],constructClazzs[1]);
            javaType =mapper.getTypeFactory().constructParametricType(clazz, dataType);
        }else{
            javaType =mapper.getTypeFactory().constructParametricType(clazz, constructClazzs);
        }
        try {
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("json to object error：{},json:{}",e.getMessage(),json);
            e.printStackTrace();
        }
        return  null;
    }*/

    /**
     * 解码json 格式：List<Object> Map<Object,Object>
     * @param json json
     * @param collectionCls 集合cls
     * @param elementCls 集合对象cls
     * @param <T> 对象类型
     * @return 对象
     */
    public <T> T decode(String json, Class<T> collectionCls, Class... elementCls) {
        try {
            JavaType javaType =mapper.getTypeFactory().constructParametricType(collectionCls, elementCls);
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("json to object error：{},json:{}",e.getMessage(),json);
            e.printStackTrace();
        }
        return  null;
    }

    /**
     * 解码json 格式：List<Object>
     * @param json json
     * @param collectionCls 集合cls
     * @param elementCls 集合对象 cls
     * @param <T> 集合类型
     * @param <E> 集合对象类型
     * @return 集合
     *//*
    public <T,E> T decode(String json, Class<T> collectionCls,Class<E> elementCls) {
        JavaType javaType =mapper.getTypeFactory().constructParametricType(collectionCls, elementCls);
        try {
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("json to object error：{},json:{}",e.getMessage(),json);
            e.printStackTrace();
        }
        return  null;
    }*/

    /**
     * 解码json 格式：Object 有属性 List<Object> Map<Object,Object>
     * @param json json
     * @param cls 对象类型
     * @param collectionCls 对象内集合类型
     * @param elementCls 对象内集合内对象类型
     * @param <T> 对象类型
     * @param <E> 集合类型
     * @return 对象
     */
    public <T,E> T decode(String json, Class<T> cls,Class<E> collectionCls,Class... elementCls) {
        try {
            JavaType collJavaType =mapper.getTypeFactory().constructParametricType(collectionCls, elementCls);
            JavaType javaType =mapper.getTypeFactory().constructParametricType(cls,collJavaType);
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            log.error("json to object error：{},json:{}",e.getMessage(),json);
            e.printStackTrace();
        }
        return  null;
    }


}
